// Thud - a dynamic object-oriented language
// Copyright (C) 2009,2010 David H. Hovemeyer <david.hovemeyer@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef VM_OPCODE_H
#define VM_OPCODE_H

#include <cwchar>

/**
 * Bytecode instruction opcodes.
 */
enum Opcode {
	/** No-op. */
	OP_NOP,
	/** Create an object. */
	OP_NEW,
	/** Duplicate top value on operand stack. */
	OP_DUP,
	/** Push a constant in the class's constant pool onto the operand stack. */
	OP_PUSH_CONST,
	/** Push a signed 8-bit integer constant onto the operand stack. */
	OP_PUSH_I8_CONST,
	/** Call a method. */
	OP_CALL,
	/** Load a local variable, pushing it onto the operand stack. */
	OP_LOAD_LOCAL,
	/**
	 * Store the value on top of the operand stack to a local variable.
	 * NOTE: the operand is left on the stack.
	 */
	OP_STORE_LOCAL,
	/** Load the value from a field of an object, pushing it onto the operand stack. */
	OP_LOAD_FIELD,
	/**
	 * Store the value on top of the operand stack to a field of an object.
	 * NOTE: the operand is left on the stack.
	 */
	OP_STORE_FIELD,
	/** Pop top value from operand stack. */
	OP_POP,
	/** Branch to an instruction. */
	OP_GOTO,
	/** Pop top operand: if true, branch to instruction. */
	OP_IFTRUE,
	/** Pop top operand: if false, branch to instruction. */
	OP_IFFALSE,
	/** Push a nil value onto the operand stack. */
	OP_PUSH_NIL,
	/** Return from method: value on top of operand stack is returned to caller. */
	OP_RETURN,
	/** Push a module reference onto the operand stack. */
	OP_PUSH_MODULE_REF,

	/** Number of bytecode instruction opcodes. */
	OP_NUM_OPCODES,
};

/** Opcode flags. */
enum OpcodeFlags {
	OP_FLAG_I8_CONST = 1,
	OP_FLAG_CP_REF = 2,
	OP_FLAG_BRANCH = 4,
};

/**
 * Get flags for given Opcode.
 */
int opcodeGetFlags(Opcode opcode);

/**
 * Get name of given Opcode.
 */
const wchar_t *opcodeGetName(Opcode opcode);

#endif
